package alfred.mdp.messages;

import org.zeromq.ZFrame;
import org.zeromq.ZMsg;

import java.util.Iterator;

import static alfred.mdp.utils.Utils.asByteArray;

/**
 */
public abstract class ProtocolMessage {
    private final ZMsg msg;
    private ZFrame clientId;

    public ProtocolMessage(ZFrame... frames) {
        this.msg = asZMsg(frames);
    }

    public ProtocolMessage(ZMsg msg) {
        this.msg = msg;
    }

    public ZFrame get(int index) {
        return get(this.msg, index);
    }

    public ZFrame getClientId() {
        return this.clientId;
    }

    public void setClientId(ZFrame clientId) {
        this.clientId = clientId;
    }

    public ZMsg getZMsg() {
        return msg;
    }

    public String getServiceName() {
        throw new UnsupportedOperationException();
    }

    public ZMsg getSubMsg(int index) {
        return getSubMsg(msg, index);
    }

    public static ZMsg getSubMsg(ZMsg msg, int index) {
        ZMsg result = msg.duplicate();
        Iterator<ZFrame> iterator = result.iterator();
        int i = 0;
        while (iterator.hasNext() && i < index) {
            iterator.next();
            iterator.remove();
            i++;
        }
        return result;
    }

    public static ZMsg asZMsg(ZFrame... frames) {
        ZMsg zMsg = new ZMsg();
        for (ZFrame frame : frames) {
            zMsg.addLast(frame.duplicate());//to fix destroy side effect of zmsg.send
        }
        return zMsg;
    }

    public static ZFrame get(ZMsg msg, int index) {
        int i = 0;
        for (ZFrame frame : msg) {
            if (i == index) {
                return frame;
            }
            i++;
        }
        throw new IndexOutOfBoundsException();
    }

    public static ZMsg asZMsg(String... datas) {
        ZMsg result = new ZMsg();
        for (String data : datas) {
            result.addLast(asByteArray(data));
        }
        return result;
    }

    public static ZFrame asZFrame(String data) {
        return new ZFrame(asByteArray(data));
    }
    //TODO:equals
}
